<?php
/**
 * Created by PhpStorm.
 * User: DQ
 * Date: 2018/9/25
 * Time: 13:38
 */
namespace App\Services\ThirdPayments\Recharge;

use App\Models\RechargeOrder;
use App\Services\ThirdPayments\Contracts\RechargeBaseAbstract;
use App\Lib\PaymentMap;
use App\Lib\ThirdPartyMap;
use App\Services\ThirdPayments\BankTraits\AIISPAYBankMap;
use App\Services\ThirdPayments\Contracts\Actions\HrefRedirectAction;
use App\Services\ThirdPayments\Contracts\Actions\HtmlPrintAction;
use App\Services\ThirdPayments\Contracts\WAPable;

class HeeypayPayment extends RechargeBaseAbstract implements WAPable
{
    use AIISPAYBankMap;

    protected $gw_pay = 'https://gateway.heeypay.com/recharge/pay';
    protected $gw_query = 'https://gateway.heeypay.com/recharge/query';

    public function callback(array $data)
    {
        // TODO: Implement callback() method.
        if ($this->veryCallbackSign($data)) {
            if ($data['err_code'] == 0) return true;
        }
        return false;
    }

    public function veryCallbackSign(array $data)
    {
        // TODO: Implement veryCallbackSign() method.
        $params = $data;
        unset($params['sign']);
        ksort($params);
        $signStr = "";
        foreach ($params as $key => $param) {
            $signStr .= $key . '=' . $param . '&';
        }
        $signStr .= $this->getMchKey();
        if (strcasecmp(md5($signStr), $data['sign']) == 0) return true;
        return false;
    }

    public function getOrderNoFromCallback(array $data)
    {
        // TODO: Implement getOrderNoFromCallback() method.
        return $data['mch_no'];
    }

    public function getOrderAmtFromCallback(array $data)
    {
        // TODO: Implement getOrderAmtFromCallback() method.
        return $data['order_amt'];
    }

    public function getThirdNoFromCallback(array $data)
    {
        return $data['plat_no'];
    }

    /**
     * @return mixed
     */
    public function getIdentify(): string
    {
        // TODO: Implement getIdentify() method.
        return ThirdPartyMap::AISHANG;
    }

    /**
     *  needs child to achieve
     */
    public function initPaymentMap(): array
    {
        // TODO: Implement initPaymentMap() method.
        return [
            PaymentMap::ALI => PaymentMap::ALI,
            PaymentMap::WX => PaymentMap::WX,
            PaymentMap::ALI_WAP => PaymentMap::ALI_WAP,
            PaymentMap::WX_WAP => PaymentMap::WX_WAP,
            PaymentMap::BANK => PaymentMap::BANK,
            PaymentMap::BANK_WAP => PaymentMap::BANK_WAP,
            PaymentMap::QQ => PaymentMap::QQ,
            PaymentMap::QQ_WAP => PaymentMap::QQ_WAP
        ];
    }

    public function query(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement query() method.
        $this->setParameter('version', '1.0');
        $this->setParameter('mch_code', $this->getMchId());
        $this->setParameter('mch_no', $rechargeOrder->plat_no);
        $this->setParameter('sign_type', 'md5');
        $this->setParameter('sign', $this->querySign());
        $res = curlHttp($this->getGwQuery(), $this->getParameters(), 'post');
        if ($res['http_code'] == 200) {
            try {
                $body = json_decode($res['body'], true);
                if ($body['status'] == 200) {
                    if ($body['state'] == 1) return true;
                    return '订单未支付';
                } else {
                    return var_export($body['messages'], true);
                }
            } catch (\Exception $exception) {
                return '异常!'.$exception->getMessage();
            }
        }
        return $res['body'];
    }

    public function bankHref(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement bankHref() method.
        $this->initParameters($rechargeOrder);
        return new HtmlPrintAction(formPostHtml($this->getGwPay(), $this->getParameters()));
    }

    public function scanCode(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement scanCode() method.
        $this->initParameters($rechargeOrder);
        return new HtmlPrintAction(formPostHtml($this->getGwPay(), $this->getParameters()));
    }

    public function paySign(): string
    {
        // TODO: Implement paySign() method.
        $params = $this->getParameters();
        ksort($params);
        $signStr = "";
        foreach ($params as $key => $param) {
            $signStr .= $key . '=' . $param . '&';
        }
        $signStr .= $this->getMchKey();
        return md5($signStr);
    }

    public function querySign(): string
    {
        // TODO: Implement querySign() method.
        $params = $this->getParameters();
        ksort($params);
        $signStr = "";
        foreach ($params as $key => $param) {
            $signStr .= $key . '=' . $param . '&';
        }
        $signStr .= $this->getMchKey();
        return md5($signStr);
    }

    public function showSuccess(): string
    {
        // TODO: Implement showSuccess() method.
        return 'success';
    }

    public function initParameters(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement initParameters() method.
        $mchData = $rechargeOrder->order_data;
        $this->setParameter('version', '1.0');
        $this->setParameter('mch_code', $this->getMchId());
        $this->setParameter('mch_no', $rechargeOrder->plat_no);
        $this->setParameter('order_amt', $rechargeOrder->order_amt);
        $this->setParameter('app_id', $this->getExt()['app_id']);
        $this->setParameter('callback_url', $this->getCallbackUrl());
        $this->setParameter('return_url', $this->getReturnUrl());
        $this->setParameter('recharge_type', $this->getPaymentMap($mchData['recharge_type']));
        if ($mchData['recharge_type'] == PaymentMap::BANK) {
            $this->setParameter('bank_code', $this->getBank($mchData['bank_code']));
        }
        $this->setParameter('order_time', date('YmdHis'));
        $this->setParameter('body', array_key_exists('body', $mchData) ? $mchData['body'] : '在线产品');
        $this->setParameter('sign_type', 'md5');
        $this->setParameter('sign', $this->paySign());
    }

    public function wapReq(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement wapReq() method.
        $this->initParameters($rechargeOrder);
        return new HtmlPrintAction(formPostHtml($this->getGwPay(), $this->getParameters()));
    }
}